package org.example.demo.apiv2.sql;

import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.schema.Column;
import org.example.demo.apiv2.constant.OperatorType;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


@Slf4j
public class OperatorParser {

    private static final String WITH_LEFT_EXPRESSION_METHOD_NAME = "withLeftExpression";
    private static final String WITH_RIGHT_EXPRESSION_METHOD_NAME = "withRightExpression";


    /**
     * 根据运算符获取Expression
     *
     * @param operator
     * @return 返回的可能是ComparisonOperator, 也可能是InExpression
     */
    public static Expression getExpressionByOperator(String operator) {
        switch (operator) {
            case OperatorType.OPERATOR_EQ:
                return new EqualsTo();
            case OperatorType.OPERATOR_NE:
                return new NotEqualsTo();
            case OperatorType.OPERATOR_GT:
                return new GreaterThan();
            case OperatorType.OPERATOR_LT:
                return new MinorThan();
            case OperatorType.OPERATOR_GE:
                return new GreaterThanEquals();
            case OperatorType.OPERATOR_LE:
                return new MinorThanEquals();
            case OperatorType.OPERATOR_LIKE:
                return new LikeExpression();
            case OperatorType.OPERATOR_IN:
                return new InExpression();
            default:
                log.error("不支持的比较运算符: {}", operator);
                throw new IllegalArgumentException("不支持的比较运算符: " + operator);
        }
    }

    /**
     * 设置Expression的leftExpression
     *
     * @param object
     * @param leftExpression
     */
    public static void setLeftExpression(Expression object, Expression leftExpression) {
        setExpression(object, leftExpression, WITH_LEFT_EXPRESSION_METHOD_NAME);
    }

    /**
     * 设置Expression的rightExpression
     *
     * @param object
     * @param rightExpression
     */
    public static void setRightExpression(Expression object, Expression rightExpression) {
        setExpression(object, rightExpression, WITH_RIGHT_EXPRESSION_METHOD_NAME);
    }

    /**
     * 利用反射调用Expression子类的withLeftExpression或withRightExpression
     * 由于Expression中没有withLeftExpression和withRightExpression,需要使用到反射
     *
     * @param object
     * @param expression
     * @param methodName
     */
    public static void setExpression(Expression object, Expression expression, String methodName) {
        try {
            Class<? extends Expression> clazz = object.getClass();
            Method method = clazz.getMethod(methodName, Expression.class);
            Object result = method.invoke(object, expression);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        Expression equalsTo = new EqualsTo();
        setLeftExpression(equalsTo, new Column("name"));
        setRightExpression(equalsTo, new StringValue("xiaohong"));
        System.out.println(equalsTo);

    }
}
